package com.ecnu.ob.test;

import java.util.Map;
import java.util.Map.Entry;

import org.junit.Assert;
import org.junit.Test;

import com.alibaba.middleware.race.rpc.api.RpcConsumer;
import com.alibaba.middleware.race.rpc.api.impl.RpcConsumerImpl;
import com.alibaba.middleware.race.rpc.async.ResponseFuture;
import com.alibaba.middleware.race.rpc.context.RpcContext;
import com.alibaba.middleware.race.rpc.demo.service.RaceConsumerHook;
import com.alibaba.middleware.race.rpc.demo.service.RaceDO;
import com.alibaba.middleware.race.rpc.demo.service.RaceException;
import com.alibaba.middleware.race.rpc.demo.service.RaceServiceListener;
import com.alibaba.middleware.race.rpc.demo.service.RaceTestService;
import com.alibaba.middleware.race.rpc.model.RpcResponse;


public class testClient {
	private static RpcConsumer consumer;
    private static RaceTestService apiService;

    static {
        consumer = new RpcConsumerImpl();
        if(consumer == null){
            System.out.println("Start rpc consumer failed");
            System.exit(1);
        }
        apiService = (RaceTestService) consumer
                .interfaceClass(RaceTestService.class)
                .version("1.0.0.api")
                .clientTimeout(3000)
                .hook(new RaceConsumerHook()).instance();

    }
    
    @Test
    public void testRpcContext() {
        RpcContext.addProp("context", "please pass me!");
        Map<String, Object> resultMap = apiService.getMap();
        Assert.assertTrue(resultMap.containsKey("context"));
        Assert.assertTrue(resultMap.containsValue("please pass me!"));
    }
    @Test
    public void testConsumerHook() {
        Map<String, Object> resultMap = apiService.getMap();
        Assert.assertTrue(resultMap.containsKey("hook key"));
        Assert.assertTrue(resultMap.containsValue("this is pass by hook"));
    }
    @Test
    public void testNormalApiCall() {
        Assert.assertNotNull(apiService.getMap());
        Assert.assertEquals("this is a rpc framework", apiService.getString());
        RaceDO do1=apiService.getDO();
        RaceDO do2=new RaceDO();
		Assert.assertEquals(do2, do1);
    }
    
    @Test
    public void testNormalSpringCall() {
        Assert.assertNotNull(apiService.getMap());
        Assert.assertEquals("this is a rpc framework", apiService.getString());
        Assert.assertEquals(new RaceDO(), apiService.getDO());
    }
    
    //@Test
    public void testTimeoutCall() {
        long beginTime = System.currentTimeMillis();
        try {
            boolean result = apiService.longTimeMethod();
        } catch (Exception e) {
            long period = System.currentTimeMillis() - beginTime;
            Assert.assertTrue(period < 3100);
        }
    }
    
    @Test
    public void testCatchException() {
        try {
            Integer result = apiService.throwException();
        } catch (RaceException e) {
        	System.out.println(e.getFlag());
            Assert.assertEquals("race", e.getFlag());
            e.printStackTrace();
        }
    }
    
    @Test
    public void testCallback() {
    	//把返回结果设置为Object
        RaceServiceListener listener = new RaceServiceListener();
        consumer.asynCall("getDO", listener);
        RaceDO nullDo = apiService.getDO();
        Assert.assertEquals(null, nullDo);
        try {
        	 RaceDO resultDo = (RaceDO) listener.getResponse();
        } catch (InterruptedException e) {
        }
        finally
        {
        	consumer.cancelAsyn("getDO");
        }
    }
    @Test
    public void testFutureCall() {
        consumer.asynCall("getString");
        String nullValue = apiService.getString();
        Assert.assertEquals(null, nullValue);

        try {
            String result = (String) ResponseFuture.getResponse(3000);
            Assert.assertEquals("this is a rpc framework", result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            consumer.cancelAsyn("getString");
        }
    }
}
